﻿using System;
using System.Collections.Generic;
using Kwd.Summary.Models;
using Kwd.Summary.Services;
using Kwd.Summary.ViewModels;
using Orchard.ContentManagement.Drivers;
using Orchard.Logging;
using Orchard.Services;

namespace Kwd.Summary.Driver
{
  /// <summary>
  /// The shapes to display for this Content part.
  /// </summary>
  public class SummaryPartDriver : ContentPartDriver<SummaryPart>
  {
    #region Fields / Const
    private IStrategyFactory _strategyFactory;
    private IEnumerable<IHtmlFilter> _htmlFlavors;

    /// <summary>
    /// Parts_Summary
    /// </summary>
    public const string DisplayPart = "Parts_Summary";

    /// <summary>
    /// Parts_Summary_Edit
    /// </summary>
    public const string EditPartName = "Parts_Summary_Edit";
    #endregion

    #region Ctor
    public SummaryPartDriver(IStrategyFactory strategyFactory, IEnumerable<IHtmlFilter> htmlFlavors)
    {
      _strategyFactory = strategyFactory;
      _htmlFlavors = htmlFlavors;
      Logger = NullLogger.Instance;
    }
    #endregion

    #region Properties
    public ILogger Logger { get; set; }

    /// <summary>
    /// Set a prefix, to identify my html fields from others.
    /// </summary>
    /// <remarks>
    /// When data is posted back, Orchard uses the prefix to identify the driver.
    /// In this way, a html input field is fed back to the correct driver.
    /// </remarks>
    protected override string Prefix
    {
      get { return "Kwd.Summary"; }
    }
    #endregion

    #region Overrides
    /// <summary>
    /// Normal display of this part.
    /// </summary>
    protected override DriverResult Display(SummaryPart part, string displayType, dynamic shapeHelper)
    {
      var shape = this.ContentShape(DisplayPart, () =>
        shapeHelper.Parts_Summary(ContentPart: part));

      return shape;
    }

    /// <summary>
    /// Part shape for editing.
    /// </summary>
    /// <remarks>
    /// Here the shape is updated to add a EditorTemplate.
    /// </remarks>
    protected override DriverResult Editor(SummaryPart part, dynamic shapeHelper)
    {
      var model = new SummaryPartEditViewModel(part);

      model.Flavor = part.Settings.GetModel<SummaryTypePartSettings>().Flavor;

      if (String.IsNullOrWhiteSpace(model.StrategyName)){
        model.StrategyName = part.Settings.GetModel<SummaryTypePartSettings>().DefaultStrategy;
      }
      
      model.StrategyOptions = new StrategyOptions(Logger).Build(_strategyFactory.List(), model.StrategyName);

      var shape = this.ContentShape(EditPartName, //shape name
        () => shapeHelper.EditorTemplate( //want an editor template dynamic shape.
        TemplateName: "Parts/Summary", //editor template expects a template name to point to the view
        Model: model, //specify the model for the view.
        Prefix: this.Prefix));//this models prefix.

      return shape;
    }

    /// <summary>
    /// Commit shape to storage using the provided
    /// <see cref="IUpdateModel"/> service.
    /// </summary>
    protected override DriverResult Editor(SummaryPart part, Orchard.ContentManagement.IUpdateModel updater, dynamic shapeHelper)
    {
      updater.TryUpdateModel(part, this.Prefix, null, null);

      //the shape to return.
      var shape = Editor(part, shapeHelper);

      return shape;
    }

    #endregion

    /// <summary>
    /// todo: can i use shapes for each strat
    /// </summary>
    /// <remarks>
    /// I would like to create shapes for each strategy, so it can be extended,
    /// but i cant work-out how to get the shapes, and add them...
    /// </remarks>
    private void CreateShapesForStrategies(dynamic shapeHelper)
    {
      //  foreach (var strat in _strategyFactory.List())
      //  {
      //    var shapeName = "SummaryStrategy" + strat.Name;

      //    var stratShape = ContentShape(shapeName, () => shapeHelper
      //      .EditorTemplate(
      //        TemplateName: "Parts/"+shapeName,
      //        Model: strat,
      //        Prefix: this.Prefix
      //      ));

      //    stratParts.Add(stratShape);

      //  model.StrategyShapes = stratShapes;
      //  //model.StrategyShapes = stratShapes;// shapeHelper.Strategies(stratShapes);
      //  //model.StrategyShapes = shapeHelper.Strategies(lstShape);
      //  //model.StrategyShapes = stratShapes.ToArray());
      //}
    }
  }
}